import java.io.*;
import java.net.*;
import java.util.HashMap;
import java.util.Map;

public class Client {
    //因为服务器用的是nginx，没有部署在云上，所以只进行本地测试
    //String url = "47.114.48.8:8080/fileServer/";

    //接口url的公共部分，根据需要在后边拼接
    static String url0 = "http://127.0.0.1:8080/fileServer/";
    //上传文件/下载文件，可以随意更改，测试
    static String dir = "/Users/eric/code/test/test.txt";
    //若更改，请先上传，取得另一可用uuid再修改
    static String uuid = "168196bb-fdfc-4e46-a9c5-4f75f74785a8";

    public static void main(String[] args) throws IOException {
        //按需测试
        callUpload();
//        callGetInfo(uuid);
//        callDownload(uuid);
    }

    /**
     * 拼装完整URL 配置通用属性 获得http连接对象
     * @param target 要访问的URL的最后一级
     * @return  HttpURLConnection http连接
     * @throws IOException
     */
    protected static HttpURLConnection getConn(String target) throws IOException {
        URL url = new URL(url0+target);
        // 打开和目标URL之间的连接
        HttpURLConnection connection = (HttpURLConnection)url.openConnection();
        connection.setDoInput(true);
        connection.setDoOutput(true);
        connection.setRequestProperty("connection", "Keep-Alive");
        return connection;
    }

    /**
     * 调用upload接口，上传文件
     * @return
     * @throws IOException
     */
    public static String callUpload() throws IOException {
        //打开，读取文件，获取文件信息和文本流
        File file = new File(dir);
        FileInputStream fileInputStream = new FileInputStream(dir);
        String fileName = file.getName();
        String fileType = fileName.split("\\.")[1];
        //jdk 11, 如果Java 8 则可用read(),逐字节读取
        byte[] bytes = fileInputStream.readAllBytes();
        String fileSize = bytes.length+"";

        //获取连接对象，配置参数，写入文本流
        HttpURLConnection connection = getConn("upload");
        connection.setRequestMethod("POST");
        connection.setRequestProperty("fileName",fileName);
        connection.setRequestProperty("fileType",fileType);
        connection.setRequestProperty("fileSize",fileSize);
        OutputStream outputStream = connection.getOutputStream();
        outputStream.write(bytes);
        outputStream.flush();
        outputStream.close();

        String uuid = new String(connection.getInputStream().readAllBytes());
        return uuid;
    }


    /**
     * 调用getInfo接口，获取元数据
     * @param uuid 传参uuid
     * @throws IOException
     */
    public static Map callGetInfo(String uuid) throws IOException {
        HttpURLConnection connection = getConn("getInfo");
        connection.setRequestMethod("GET");
        connection.setRequestProperty("uuid",uuid);
        connection.getOutputStream().flush();
        connection.getOutputStream().close();
        byte[] bytes = connection.getInputStream().readAllBytes();
        Map<String , String> map = transInfo(bytes);
        return map;
    }

    /**
     * 将byte[]类型的传输数据，切割转化为可读的Map
     * @param bytes 网络传输数据
     * @return Map对象 通过键值对取值
     */
    public static Map transInfo(byte[] bytes){
        String str = new String(bytes);
        str = str.split("\\{")[1];
        str = str.split("\\}")[0];
        int num = str.split(",").length;
        Map<String , String> map = new HashMap<String , String>();
        String temp = "";
        for(int i=0; i<num; i++){
            temp = str.split(",")[i];
            map.put(temp.split("=")[0],temp.split("=")[1]);
        }
        return map;
    }


    /**
     * 调用download接口，获取文件流，将其写入本地
     * @param uuid 传参uuid
     * @throws IOException
     */
    public static void callDownload(String uuid) throws IOException {
        HttpURLConnection connection = getConn("download");
        connection.setRequestMethod("GET");
        connection.setDoOutput(true);
        connection.setRequestProperty("uuid",uuid);
        connection.getOutputStream().flush();
        connection.getOutputStream().close();
        byte[] bytes = connection.getInputStream().readAllBytes();
        writeFile(dir,bytes);
    }

    /**
     * 创建文件，进行文本写入
     * @param dir String 文件路径
     * @param text byte[] 文本内容
     * @throws IOException
     */
    public static void writeFile(String dir, byte[] text) throws IOException {
        FileOutputStream fileOutputStream;
        BufferedOutputStream bufferedOutputStream;
        fileOutputStream = new FileOutputStream(dir);
        bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
        bufferedOutputStream.write(text,0,text.length);
        bufferedOutputStream.flush();
        bufferedOutputStream.close();
    }
}
